// 包含计算温湿度的模块
#include "dht11.h"

// 定义用于计算温湿度的变量
dht11 DHT11;

// 温湿度引脚定义
#define DHT11PIN 2
// 定义限位器引脚
#define CrashPIN 3
// 定义可燃气体引脚
#define FirePIN 4
// 定义排气继电器引脚
#define AirPIN 5
// 定义照明LED引脚
#define LightPIN 6
// 定义加热继电器引脚
#define KeepTempPIN 7

// 定义温度变量
float temp = 0;
// 定义限位器变量
int crash = 0;
// 定义可燃气体变量
int fire = 0;
// 定义排气继电器变量
int air = 0;
// 定义照明LED变量
int light = 0;
// 定义加热继电器变量
int keepTemp = 0;

// 定义字符串接收缓冲区
String data = "";
// 定义发送数据的时间间隔
int data_send_interraval = 2000;
int data_send_counter = 0;

/*获取当前温度*/
void getTemp() {
  // 读取温度并判断是否读取成功
  int chk = DHT11.read(DHT11PIN);
  if (DHTLIB_OK == chk) {
    temp = (float)DHT11.temperature;
  } else {
    temp = 0;
  }
}

/*获取限位器*/
void getCrash() {
  crash = !digitalRead(CrashPIN);
}

/*获取可燃气体*/
void getFire() {
  fire = !digitalRead(FirePIN);
}

/*设置排气*/
void setAir() {
  if (air) {
    digitalWrite(AirPIN, HIGH);
  } else {
    digitalWrite(AirPIN, LOW);
  }
}

/*设置照明*/
void setLight() {
  if (light) {
    digitalWrite(LightPIN, HIGH);
  } else {
    digitalWrite(LightPIN, LOW);
  }
}

/*设置加热恒温*/
void setKeepTemp() {
  if (keepTemp) {
    digitalWrite(KeepTempPIN, HIGH);
  } else {
    digitalWrite(KeepTempPIN, LOW);
  }
}

/*采集数据并发送数据*/
void sampleAndSendData() {
  getTemp();
  getCrash();
  getFire();
  // 采用json数据包的方式将数据发送出去
  Serial.print("{\"temp\":");
  Serial.print(temp);
  Serial.print(",\"crash\":");
  Serial.print(crash);
  Serial.print(",\"fire\":");
  Serial.print(fire);
  Serial.print(",\"air\":");
  Serial.print(air);
  Serial.print(",\"light\":");
  Serial.print(light);
  Serial.print(",\"keepTemp\":");
  Serial.print(keepTemp);
  Serial.println("}");
}

/*解析上位机发送的json数据并进行相应的设置*/
void resolveJsonAndSetHardWare(String json) {
  // 完整的json数据包格式
  // {"L":0,"A":1,"K":1}

  // 处理照明
  if (json[5] == '0') {
    light = 0;
  } else {
    light = 1;
  }
  setLight();

  // 处理排气
  if (json[11] == '0') {
    air = 0;
  } else {
    air = 1;
  }
  setAir();

  // 处理恒温
  if (json[17] == '0') {
    keepTemp = 0;
  } else {
    keepTemp = 1;
  }
  setKeepTemp();
}

void setup() {
  // [0] 初始化串口
  Serial.begin(115200);

  // [1] 初始化其它相关的引脚
  pinMode(CrashPIN, INPUT);
  pinMode(FirePIN, INPUT);
  pinMode(AirPIN, OUTPUT);
  pinMode(LightPIN, OUTPUT);
  pinMode(KeepTempPIN, OUTPUT);

  // [2] 设置默认状态
  setAir();
  setLight();
  setKeepTemp();
}

void loop() {
  // [0] 获取控制状态信息并进行相应的数据解析
  while (Serial.available() > 0) {
    data += char(Serial.read());
    delay(2);
  }
  // [1] json 数据接收完成
  if (data[0] == '{' && data[18] == '}') {
    resolveJsonAndSetHardWare(data);
    data = "";
  }

  // [2] 判断是否到了发送数据的时间
  if (data_send_interraval == data_send_counter) {
    // (0) 采集一次数据并发送数据
    sampleAndSendData();
    data_send_counter = 0;
  } else {
    data_send_counter += 10;
  }
  // 适当延时避免数据缓冲区溢出
  delay(10);
}
